package com.doudou.base.resources.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.doudou.base.resources.dao.UserAccountInfoDao;
import com.doudou.base.resources.entity.UserAccountInfo;
import com.doudou.base.resources.entity.dto.user.account.UserAccountInfoAddDto;
import com.doudou.base.resources.entity.dto.user.account.UserAccountInfoUpdateDto;
import com.doudou.base.resources.entity.dto.user.details.UserDetailsInfoAddDto;
import com.doudou.base.resources.service.UserAccountInfoService;
import com.doudou.base.resources.service.UserDetailsInfoService;
import com.doudou.client.entity.UserAccountInfoDto;
import com.doudou.client.entity.UserDetailsInfoDto;
import com.doudou.commons.constant.AccountType;
import com.doudou.commons.entity.PageInfo;
import com.doudou.commons.entity.PaginationSupport;
import com.doudou.commons.regex.RegexContext;
import com.doudou.commons.utils.ConvertBeanUtils;
import com.doudou.commons.utils.ListUtils;
import com.doudou.commons.utils.MyAssert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

/**>
 * 用户账号的详情 服务实现类
 *
 * @author 傻男人
 * @since 2020-05-14
 */
@Slf4j
@Service
public class UserAccountInfoServiceImpl  implements UserAccountInfoService {

    @Autowired
    UserAccountInfoDao userAccountInfoDao;

    @Autowired
    private UserDetailsInfoService userDetailsInfoService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
    * 添加用户账号的详情
    * @param userAccountInfoAddDto
    * @return
    */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserAccountInfoDto addUserAccountInfo(UserAccountInfoAddDto userAccountInfoAddDto) {
        UserAccountInfo userAccountInfo = ConvertBeanUtils.copyProperties(userAccountInfoAddDto,UserAccountInfo.class);
        userAccountInfo.setAvailable(0);
        userAccountInfoDao.insert(userAccountInfo);
        return ConvertBeanUtils.copyProperties(userAccountInfo,UserAccountInfoDto.class);
    }

    /**
     * 根据ids删除用户账号的详情
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteUserAccountInfo(String ids) {
        List<Long> listId = ListUtils.strToLongList(ids);
        QueryWrapper<UserAccountInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in(UserAccountInfo.Meta.id,listId);

        UserAccountInfo userAccountInfo = new UserAccountInfo();
        userAccountInfo .setDelFlag(1);
        userAccountInfo .setUpdateDate(new Date());
        return userAccountInfoDao.update(userAccountInfo, queryWrapper);
    }

    /**
     * 检查手机是否已经存在
     * @param phone
     * @return
     */
    public boolean checkPhoneExist(String phone){
        QueryWrapper<UserAccountInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(UserAccountInfo.Meta.phone,phone);
        queryWrapper.eq(UserAccountInfo.Meta.delFlag,0);

        Integer count = userAccountInfoDao.selectCount(queryWrapper);
        if(count > 0){
            return true;
        }
        return false;
    }

    /**
     * 检查邮箱是否已经存在
     * @param email
     * @return
     */
    public boolean checkEmailExist(String email){
        QueryWrapper<UserAccountInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(UserAccountInfo.Meta.email,email);
        queryWrapper.eq(UserAccountInfo.Meta.delFlag,0);

        Integer count = userAccountInfoDao.selectCount(queryWrapper);
        if(count > 0){
            return true;
        }
        return false;
    }

    /**
     * 检查登录用户名是否已经存在
     * @param loginName
     * @return
     */
    public boolean checkLoginNameExist(String loginName){
        QueryWrapper<UserAccountInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(UserAccountInfo.Meta.loginName,loginName);
        queryWrapper.eq(UserAccountInfo.Meta.delFlag,0);

        Integer count = userAccountInfoDao.selectCount(queryWrapper);
        if(count > 0){
            return true;
        }
        return false;
    }

    /**
     * 根据id修改用户账号的详情
     * @param userAccountInfoUpdateDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateUserAccountInfo(UserAccountInfoUpdateDto userAccountInfoUpdateDto) {
        //检查传入的id是否正确
        UserAccountInfo userAccountInfo = userAccountInfoDao.selectById(userAccountInfoUpdateDto.getId());
        if(null == userAccountInfo){
            log.info("修改的数据不存在");
            return null;
        }
        userAccountInfo = ConvertBeanUtils.copyProperties(userAccountInfoUpdateDto,UserAccountInfo.class);
        return userAccountInfoDao.updateById(userAccountInfo);
    }

    /**
     * 根据ids查询用户账号的详情
     * @param ids
     * @return
     */
    @Override
    public List<UserAccountInfoDto> findUserAccountInfo(String ids) {
        List<Long> listIds = ListUtils.strToLongList(ids);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.in(UserAccountInfo.Meta.id,listIds);
        queryWrapper.eq(UserAccountInfo.Meta.delFlag,0);
        List<UserAccountInfo> userAccountInfos = userAccountInfoDao.selectList(queryWrapper);
        return ListUtils.copyList(userAccountInfos,UserAccountInfoDto.class);
    }

    /**
     * 根据id查询用户账号的详情
     * @param primaryId
     * @return
     */
    @Override
    public UserAccountInfoDto findUserAccountInfoById(Long primaryId){
        UserAccountInfo userAccountInfo = userAccountInfoDao.selectById(primaryId);
        if(userAccountInfo == null || userAccountInfo.getDelFlag() != 0 ){
            return null;
        }
        return ConvertBeanUtils.copyProperties(userAccountInfo,UserAccountInfoDto.class);
    }

    @Override
    public UserDetailsInfoDto findByUsernameAndPassword(String username, String password) {
        MyAssert.notNull(password,"密码不能为空");
        UserAccountInfoDto userAccountInfoDto = findByUsername(username);
        MyAssert.state(passwordEncoder.matches(password, userAccountInfoDto.getPassword()),"用户名或者密码错误");
        isAccountValid(userAccountInfoDto);
        return userDetailsInfoService.findUserDetailsInfoByUserId(userAccountInfoDto.getId());
    }

    /**
     * 验证账号是否有效
     * @param userAccountInfoDto
     * @return  无效时会抛异常
     */
    private boolean isAccountValid(UserAccountInfoDto userAccountInfoDto){
        if(userAccountInfoDto.getAvailable() == 1 || userAccountInfoDto.getDelFlag() == 1){
            throw new RuntimeException("用户账号被锁定或者无效");
        }
        return true;
    }
    /**
     * 根据用户名查询用户信息
     *
     * @param username
     * @return
     */
    @Override
    public UserAccountInfoDto findByUsername(String username) {
        MyAssert.notNull(username,"用户名不能为空");
        UserAccountInfoDto userAccountInfoDto = null;
        //判断用户账号类型
        if(Pattern.matches(username, RegexContext.phone)){
            userAccountInfoDto = findUserAccountInfoByPhone(username);
        }else if(Pattern.matches(username, RegexContext.email)){
            userAccountInfoDto = findUserAccountInfoByEmail(username);
        }else {
            userAccountInfoDto = findUserAccountInfoByLoginName(username);
        }
        if(userAccountInfoDto == null){
            return null;
        }
        return userAccountInfoDto;
    }

    /**
     * 根据用户手机号查询 如果没有找到就用手机号作为注册账号
     *
     * @param phone
     * @return
     */
    @Override
    public UserAccountInfoDto findNoRegisterByPhone(String phone) {
        UserAccountInfoDto userAccountInfoDto = findUserAccountInfoByPhone(phone);
        if(userAccountInfoDto != null){
            isAccountValid(userAccountInfoDto);
            return userAccountInfoDto;
        }
        //数据库木有  则需要添加
        userAccountInfoDto = addUserAccountInfo(new UserAccountInfoAddDto(phone, AccountType.phone));
        UserDetailsInfoAddDto userDetailsInfoAddDto = new UserDetailsInfoAddDto();
        userDetailsInfoAddDto.setNikeName(phone);
        userDetailsInfoAddDto.setUserAccountInfoId(userAccountInfoDto.getId());
        userDetailsInfoService.addUserDetailsInfo(userDetailsInfoAddDto);
        return userAccountInfoDto;
    }

    @Override
    public PaginationSupport<UserAccountInfoDto> findPageHelper(PageInfo pageInfo) {
        Page page = new Page(pageInfo.getPageIndex(),pageInfo.getPageSize());
        IPage result = userAccountInfoDao.selectPage(page, null);
        return PaginationSupport.instance(result);
    }

    public UserAccountInfoDto findUserAccountInfoByLoginName(String loginName){
        MyAssert.notNull(loginName,"用户名不能为空");
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(UserAccountInfo.Meta.loginName,loginName);
        queryWrapper.eq(UserAccountInfo.Meta.delFlag,0);
        List<UserAccountInfo> result = userAccountInfoDao.selectList(queryWrapper);
        return ListUtils.fetchOne(result,UserAccountInfoDto.class);
    }

    public UserAccountInfoDto findUserAccountInfoByEmail(String email){
        MyAssert.notNull(email,"邮箱不能为空");
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(UserAccountInfo.Meta.email,email);
        queryWrapper.eq(UserAccountInfo.Meta.delFlag,0);
        List<UserAccountInfo> result = userAccountInfoDao.selectList(queryWrapper);
        return ListUtils.fetchOne(result,UserAccountInfoDto.class);
    }

    public UserAccountInfoDto findUserAccountInfoByPhone(String phone){
        MyAssert.notNull(phone,"手机号码不能为空");
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(UserAccountInfo.Meta.phone,phone);
        queryWrapper.eq(UserAccountInfo.Meta.delFlag,0);
        List<UserAccountInfo> result = userAccountInfoDao.selectList(queryWrapper);
        return ListUtils.fetchOne(result,UserAccountInfoDto.class);
    }

}
